package cn.xp1997.shiro.x.realm;


import cn.xp1997.shiro.x.exception.AuthenticationAuthorizationInfoException;
import cn.xp1997.shiro.x.info.AuthenticationAuthorizationInfo;
import cn.xp1997.shiro.x.info.RolePermissionInfo;
import cn.xp1997.shiro.x.token.TokenX;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.List;


/**
 * 缓存realm 认证授权信息从缓存中获取
 * @author xp
 */
public abstract class InfoRealm extends AuthorizingRealm {


    private List<AuthenticationAuthorizationInfo> infos;

    public void setAuthenticationAuthorizationInfos(List<AuthenticationAuthorizationInfo> infos){
        this.infos = infos;
    }

    private AuthenticationAuthorizationInfo getInfo(String token){
        for (AuthenticationAuthorizationInfo info : infos) {
            boolean support = info.tokenSupport(token);
            if(support){
                return info;
            }
        }
        throw new AuthenticationAuthorizationInfoException("no AuthenticationAuthorizationInfo found");
    }

    /**
     * 获取授权信息
     */
    AuthorizationInfo getAuthorizationInfoCache(PrincipalCollection principalCollection) {
        String token = (String) principalCollection.getPrimaryPrincipal();
        RolePermissionInfo rolePermissionInfo = getInfo(token).getAuthorizationInfo(token);
        SimpleAuthorizationInfo authorizationInfo =  new SimpleAuthorizationInfo();

        //设置permission
        if(null != rolePermissionInfo.getPermissions()){
            authorizationInfo.setStringPermissions(rolePermissionInfo.getPermissions());
        }
        //设置role
        if(null != rolePermissionInfo.getRoles()){
            authorizationInfo.addRoles(rolePermissionInfo.getRoles());
        }

        return authorizationInfo;
    }

    /**
     * 获取认证信息
     * @return 获取到认证信息 返回AuthenticationInfo对象 未获取到认证信息 返回null
     */
    AuthenticationInfo getAuthenticationInfoCache(AuthenticationToken authenticationToken) {
        //传入的token
        TokenX tokenX = (TokenX) authenticationToken;
        //获取info得到的token
        String token = getInfo((String) tokenX.getCredentials()).getAuthenticationInfo((String) tokenX.getCredentials());
        //判断是否获取到认证信息
        if(null == token || "".equals(token)){
            //未获取到认证信息 返回null
            return null;
        }
        //获取到认证信息返回认证对象
        return new SimpleAuthenticationInfo(
                token,
                token,
                getName());
    }

}
